package model

import (
	"time"

	"gorm.io/gorm"
)

type Location struct {
	ID        int64          `json:"-" gorm:"primaryKey;column:id;AUTO_INCREMENT;comment:主键ID;"`
	CreatedAt time.Time      `json:"-" gorm:"index;column:created_at;comment:创建时间;"`
	UpdatedAt time.Time      `json:"-" gorm:"column:updated_at;comment:更新时间;"`
	DeletedAt gorm.DeletedAt `json:"-" gorm:"column:deleted_at;comment:删除时间;"`

	SN             string  `json:"sn" gorm:"index;column:sn;comment:设备SN;"`
	Time           string  `json:"data_time" gorm:"index;column:data_time;comment:定位时间;"`
	WGS84Longitude float64 `json:"wgs84_longitude" gorm:"column:wgs84_longitude;comment:经度;"`
	WGS84Latitude  float64 `json:"wgs84_latitude" gorm:"column:wgs84_latitude;comment:纬度;"`
	GCJ02Longitude float64 `json:"gcj02_longitude" gorm:"column:gcj02_longitude;comment:高德经度;"`
	GCJ02Latitude  float64 `json:"gcj02_latitude" gorm:"column:gcj02_latitude;comment:高德纬度;"`
	BD09Longitude  float64 `json:"bd09_longitude" gorm:"column:bd09_longitude;comment:百度经度;"`
	BD09Latitude   float64 `json:"bd09_latitude" gorm:"column:bd09_latitude;comment:百度纬度;"`
}

func (Location) TableName() string {
	return "location"
}

func StoreLocation(db *gorm.DB, data *Location) error {
	return db.Model(&Location{}).Create(data).Error
}

func ListLocation(db *gorm.DB, sn string, start, end string) ([]*Location, error) {
	var res []*Location

	err := db.Model(&Location{}).Where("sn = ?", sn).
		Where("data_time >= ?", start).Where("data_time <= ?", end).Order("data_time asc").Find(&res).Error
	if err != nil {
		return nil, err
	}

	return res, nil
}

func FindLastBySN(db *gorm.DB, sn string) (*Location, error) {
	var res *Location

	err := db.Model(&Location{}).Where("sn = ?", sn).Order("data_time desc").First(&res).Error
	if err != nil {
		return nil, err
	}

	return res, nil
}

func FindLastBySNList(db *gorm.DB, list []string) ([]*Location, error) {
	sql := `select l.* from location l left join 
(
	select max(data_time) as data_time, sn from location l where sn in(?) group by sn
) as ll 
on l.sn = ll.sn where l.data_time = ll.data_time`

	var res = make([]*Location, 0)

	if err := db.Model(&Location{}).Raw(sql, list).Scan(&res).Error; err != nil {
		return nil, err
	}
	return res, nil
}
